package com.iocup.keybastion.context;


import com.iocup.keybastion.common.Cookie;
import com.pine.sunflower.core.utils.JsonUtils;

import java.util.Collection;
import java.util.Map;
import java.util.Optional;

/**
 * 全局 Request 和 Response 功能集合 上下文持有者
 *
 * @author xyjxust
 * @create 2022/2/24
 **/
public interface WebContextHolder {

    /**
     * 获取请求参数中的值
     *
     * @param name
     * @return
     */
    default Optional<String> getRequestParameter(String name) {
        return Optional.ofNullable(getRequestParameters().get(name));
    }

    /**
     * 获取所有的参数
     *
     * @return
     */
    Map<String, String> getRequestParameters();

    /**
     * 获取 attribute
     *
     * @param name key
     * @return
     */
    Optional getRequestAttribute(String name);

    /**
     * set attribute
     *
     * @param name  key
     * @param value value
     */
    WebContextHolder setRequestAttribute(String name, Object value);

    /**
     * 获取请求的方法  get、post、put等
     *
     * @return
     */
    String getRequestMethod();

    /**
     * 获取路由地址
     *
     * @return
     */
    String getRemoteAddress();


    /**
     * 在 [请求头] 里获取一个值
     *
     * @param name 键
     * @return 值
     */
    Optional<String> getRequestHeader(String name);

    /**
     * 在 [请求头] 里获取一个值
     *
     * @param name         键
     * @param defaultValue 值为空时的默认值
     * @return 值
     */
    default String getRequestHeader(String name, String defaultValue) {
        Optional<String> value = getRequestHeader(name);
        if (!value.isPresent()) {
            return defaultValue;
        }
        return value.get();
    }

    /**
     * 设置header
     *
     * @param name
     * @param value
     */
    WebContextHolder setResponseHeader(String name, String value);

    /**
     * 获取一个header
     *
     * @param name
     * @return
     */
    Optional<String> getResponseHeader(String name);

    /**
     * 设置内容类型
     *
     * @param content
     */
    WebContextHolder setResponseContentType(String content);

    /**
     * 获取请求中的cookie
     *
     * @return
     */
    Collection<Cookie> getRequestCookies();

    /**
     * 在 [Cookie作用域] 里获取一个值
     *
     * @param name 键
     * @return 值
     */
    default Optional<String> getCookieValue(String name) {
        Collection<Cookie> cookies = getRequestCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie != null && name.equals(cookie.getName())) {
                    return Optional.ofNullable(cookie.getValue());
                }
            }
        }
        return Optional.empty();
    }

    /**
     * 获取请求的url
     *
     * @return
     */
    String getRequestURL();

    /**
     * 获取全路径的请求路径
     *
     * @return
     */
    String getFullRequestURL();

    /**
     * 响应中添加cookies
     *
     * @param cookie
     */
    WebContextHolder addResponseCookie(Cookie cookie);

    /**
     * 设置response的状态
     *
     * @param status
     * @return
     */
    WebContextHolder setResponseStatus(int status);

    /**
     * 写入指定Cookie
     *
     * @param name    Cookie名称
     * @param value   Cookie值
     * @param path    Cookie路径
     * @param domain  Cookie的作用域
     * @param timeout 过期时间 （秒）
     */
    WebContextHolder addCookie(String name, String value, String path, String domain, int timeout);

    /**
     * 在响应头写入 [Server] 服务器名称
     *
     * @param value
     * @return
     */
    default WebContextHolder setResponseServer(String value) {
        return this.setResponseHeader("Server", value);
    }

    /**
     * response重定向到某个url
     *
     * @param url
     */
    void responseRedirect(String url);

    void forward(String path);

    /**
     * response返回数据
     *
     * @param o
     */
    void responseOutput(Object o);

    /**
     * 获取body内容
     *
     * @return
     */
    default Optional<String> getRequestContent() {
        throw new RuntimeException("未实现getRequestContent");
    }

    default Map<String,String> getRequestBody() {
        return getRequestContent().map(s -> JsonUtils.toObject(s, Map.class)).orElse(null);
       // return Optional.ofNullable(getRequestContent().orElse(JsonUtils.toString(new HashMap<>()) )).map(s -> JsonUtils.toObject(s, Map.class)).orElse(null);
    }

    /**
     * @return
     */
    default String getProtocol() {
        return "HTTP/1.0";
    }


}
